home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 47.7z / BS1 part 47 / Amiga plus 2 (1989)(Amiga Plus Magazine)[h QTX].7z / Amiga plus 2 (1989)(Amiga Plus Magazine)[h QTX].adf / Programming / calcffp.asm < prev    next >
Assembly Source File  |  1989-03-03  |  6KB  |  214 lines

  1. ;CALCFFP.ASM BY DANIEL WOLF 02/18/89
  2. ;WITH FLOATING POINT (FFP SINGLE PRECISION) CONVERSION ROUTINES BY DANIEL WOLF
  3. ;COPYRIGHT 1989 BY DANIEL WOLF Ph.D.
  4.  
  5. LVO.SPFIX         EQU $FFFFFFE2     ; -30
  6. LVO.SPFLT         EQU $FFFFFFDC     ; -36
  7. LVO.SPCMP         EQU $FFFFFFD6     ; -42
  8. LVO.SPTST         EQU $FFFFFFD0     ; -48
  9. LVO.SPABS         EQU $FFFFFFCA     ; -54
  10. LVO.SPNEG         EQU $FFFFFFC4     ; -60
  11. LVO.SPADD         EQU $FFFFFFBE     ; -66
  12. LVO.SPSUB         EQU $FFFFFFB8     ; -72
  13. LVO.SPMUL         EQU $FFFFFFB2     ; -78
  14. LVO.SPDIV         EQU $FFFFFFAC     ; -84
  15.  
  16. LVO.OUTPUT        EQU $FFFFFFC4     ; -60
  17. LVO.WRITE         EQU $FFFFFFD0     ; -48
  18.  
  19. LVO.OPENLIBRARY   EQU $FFFFFDD8     ; -552
  20. LVO.CLOSELIBRARY  EQU $FFFFFE62     ; -414
  21.  
  22.  
  23. MAIN
  24.  MOVE.L A0,A5           ;SAVE POINTER TO THE ASCII #S TYPED IN
  25.  MOVE.L $4,A6           ;USE FIXED EXECBASE POINTER
  26.  
  27.  LEA DOSNAME,A1         ;OPEN DOS LIBRARY
  28.  CLR.L D0
  29.  JSR LVO.OPENLIBRARY(A6)
  30.  MOVE.L D0,A4           ;SAVE ITS BASE ADDRESS
  31.  BEQ QUIT2
  32.  
  33.  LEA MATHNAME,A1        ;OPEN MATH LIBRARY
  34.  CLR.L D0
  35.  JSR LVO.OPENLIBRARY(A6)
  36.  MOVE.L D0,A3           ;SAVE ITS BASE AS WELL
  37.  BEQ QUIT1
  38.  
  39.  MOVE.L A5,A0           ;NOW GET THE FIRST #
  40.  BSR ASCTOFFP           ;CONVERT TO FFP FORMAT
  41.  BNE QUIT0
  42.  MOVE.L D0,D6
  43.  
  44.  MOVE.L A5,A0           ;POINT A0 TO NEXT NUMBER
  45.  MOVE.B -(A5),D7        ;KEEP OPERATOR IN D7
  46.  BSR ASCTOFFP           ;CONVERT 2ND # TO FFP
  47.  BNE QUIT0
  48.  
  49.  MOVE.L D6,D1
  50.  EXG D0,D1
  51.  
  52.  CMPI.B #'*',D7
  53.  BEQ MULTIPLYEM
  54.  CMPI.B #'/',D7
  55.  BEQ DIVIDEM
  56.  CMPI.B #'-',D7
  57.  BEQ SUBTRACTEM
  58.  
  59. ADDEM
  60.  JSR LVO.SPADD(A3)
  61.  
  62. FFPTOASC                ;CONVERT RESULT IN D0 BACK TO ASCII
  63.  LEA DECBUF2,A0         ;ROUTINE GOOD FOR UP TO 16 DIGITS TOTAL ACCURACY
  64.  BTST.L #7,D0           ;IS THE FFP # NEGATIVE?
  65.  BEQ POSITIVEFFP
  66.  MOVE.B #'-',(A0)       ;YES, PUT NEG SIGN INTO ASCII BUFFER
  67. POSITIVEFFP
  68.  BCLR.L #7,D0           ;WORK WITH IT AS POSITIVE
  69.  ADDA.L #1,A0
  70.  MOVE.L D0,D7           ;HIDE IT IN D7
  71.  MOVE.L #$BEBC205B,D6   ;FIRST POWER OF 10 IS 10^8
  72.  MOVE.W #16,D4          ;MAX POWER OF 10 DIVIDES
  73. DIVPOWEROFTEN
  74.  TST.W D4
  75.  BEQ ENDFFPTDA
  76.  SUBQ.W #1,D4           ;DEC POWER OF 10 BY 1
  77.  ADDA.L #1,A0           ;ADVANCE POINTER BY 1
  78.  CMPI.W #7,D4
  79.  BNE NOTDECPOINT
  80.  MOVE.B #'.',(A0)+
  81.  MOVE.L #$CCCCCC3D,D0   ;ONE TENTH IN FFP NOTATION
  82.  BRA PASTDECPOINT
  83. NOTDECPOINT
  84.  MOVE.L D6,D0           ;BRING CURRENT POWER OF 10 INTO D0
  85.  MOVE.L #$A0000044,D1   ;DIVIDE BY 10 IN FFP NOTATION
  86.  JSR LVO.SPDIV(A3)
  87. PASTDECPOINT
  88.  MOVE.B #'0',(A0)       ;ZERO THIS SPOT IN THE BUFFER
  89.  MOVE.L D0,D1           ;PUT POWER OF 10 INTO D1
  90.  MOVE.L D0,D6           ;SAVE POWER OF 10 IN D6
  91.  MOVE.L D7,D0           ;PUT CURRENT VALUE OF FFP NUMBER INTO D0
  92. COMPWITHPOWER
  93.  JSR LVO.SPCMP(A3)      ;COMPARE POWER OF 10 WITH FFP NUMBER - TRASHES REGS!
  94.  BLT DIVPOWEROFTEN
  95. SUBPOWEROFTEN
  96.  MOVE.L D7,D0           ;FFP # INTO D0
  97.  MOVE.L D6,D1           ;POWER INTO D1
  98.  JSR LVO.SPSUB(A3)
  99.  MOVE.L D0,D7           ;SAVE CURRENT VALUE OF FFP NUMBER
  100.  ADD.B #1,(A0)          ;ADD 1 TO THE DIGIT AT THIS POWER OF 10
  101.  BRA COMPWITHPOWER
  102. ENDFFPTDA
  103.  
  104. STRIP                   ;STRIP LEADING ZEROS IN THE ASCII BUFFER
  105.  LEA DECBUF2+1,A0
  106. STRIPMORE
  107.  MOVE.B (A0),D0
  108.  CMPI.B #'0',D0
  109.  BNE NOWRITE
  110.  MOVE.B #' ',(A0)+
  111.  BRA STRIPMORE
  112. NOWRITE
  113.  JSR LVO.OUTPUT(A4)     ;GRAB THE OUTPUT FILE HANDLE FOR THIS CLI
  114.  MOVE.L D0,D1
  115.  MOVE.L #DECBUF,D2      ;DECBUF HAS THE ASCII RESULT OF OPERATION
  116.  MOVE.L #23,D3
  117.  JSR LVO.WRITE(A4)      ;WRITE OUT THE ASCII RESULT
  118. QUIT0
  119.  MOVE.L A3,A1           ;CLOSE DOWN LIBRARIES
  120.  JSR LVO.CLOSELIBRARY(A6)
  121. QUIT1
  122.  MOVE.L A4,A1
  123.  JSR LVO.CLOSELIBRARY(A6)
  124. QUIT2                   ;AND HOME, JEEVES.
  125.  RTS
  126.  
  127. DIVIDEM
  128.  JSR LVO.SPDIV(A3)
  129.  BRA FFPTOASC
  130. MULTIPLYEM
  131.  JSR LVO.SPMUL(A3)
  132.  BRA FFPTOASC
  133. SUBTRACTEM
  134.  JSR LVO.SPSUB(A3)
  135.  BRA FFPTOASC
  136.  
  137.  
  138. ASCTOFFP                ;SUBROUTINE TO CONVERT ASCII TO FFP NOTATION
  139.                         ;ENTER W/ A0 POINTING TO ASCII DECIMAL TEXT
  140.                         ;EXIT WITH FFP NUMBER IN D0
  141.                         ;ERROR INDICATOR IS D1 - 0 MEANS OK
  142.                         ;                        1 MEANS ERROR
  143.  CLR.L D5
  144.  CMPI.B #'-',(A0)       ;IS IT A NEGATIVE NUMBER?
  145.  BNE.S CONVERTPOS
  146.  MOVE.B #128,D5         ;YES, SET UP SIGN BIT FOR CORRECTION TO RESULT
  147.  ADDA.L #1,A0           ;AND MOVE ADDRESS POINTER BEYOND THE NEG SIGN
  148.  
  149. CONVERTPOS              ;CONVERT POSITIVE ASCII DECIMAL TO BINARY NUMBER
  150.  CLR.L D0               ;REGISTER TO ACCUMULATE THE BINARY CONVERSION
  151.  CLR.L D2
  152.  CLR.L D4
  153. GETDIG
  154.  MOVE.B (A0)+,D3        ;GET ASCII DECIMAL DIGIT BYTE
  155.  CMPI.B #'.',D3         ;HIT THE DP?
  156.  BNE TESTDIG            ;NOPE, GO ON
  157.  MOVEQ #1,D4            ;YUP, SET RIGHT OF DP FLAG AND GRAB ANOTHER DIGIT
  158.  CLR.L D2
  159.  BRA GETDIG
  160. TESTDIG
  161.  CMPI.B #'9',D3         ;CHECK THAT IT IS REALLY AN ASCII DECIMAL DIGIT
  162.  BHI.S NOMORE           ;IF NOT A DIGIT, MOVE ON
  163.  CMPI.B #'0',D3
  164.  BLT.S NOMORE           ;IF NOT A DIGIT, MOVE ON
  165.  ANDI.L #$0F,D3         ;STRIP DOWN TO 4 BITS (STRIP THE ASCII)
  166.  
  167.  LSL.L #1,D0            ;MULTIPLY EXISTING BINARY NUMBER BY 10
  168.  MOVE.L D0,D1           ;FIRST DOUBLE, THEN DOUBLE TWICE MORE AND ADD
  169.  LSL.L #2,D0            ;THATS THE SAME AS 2X + 8X
  170.  ADD.L D1,D0
  171.  ADD.L D3,D0            ;AND ADD IN THE NEW DECIMAL DIGIT
  172.  
  173.  ADDQ.B #1,D2           ;INC # OF DIGITS EITHER SIDE OF DP
  174.  CMPI.B #8,D2           ;REACHED 8 (THE MAXIMUM HERE)?
  175.  BNE.S GETDIG           ;NO, GET ANOTHER ASCII DECIMAL DIGIT
  176. FFPERR
  177.  MOVEQ #1,D1
  178.  RTS
  179.  
  180. NOMORE
  181.  MOVE.L A0,A5           ;SAVE POINTER TO NEXT #
  182.  JSR LVO.SPFLT(A3)      ;MAKE THIS # INTO FLOATING POINT
  183.  TST.L D4
  184.  BEQ JUSTLEFT           ;SKIP FRACTIONIZING IF THERES NO FRACTION
  185.  SUBQ.L #1,D2
  186.  BMI.S JUSTLEFT
  187. FRACTIONIZE             ;DIVIDE BY 10 ONCE FOR EACH DIGIT RIGHT OF THE DP
  188.  MOVE.L #$A0000044,D1
  189.  JSR LVO.SPDIV(A3)
  190.  DBRA D2,FRACTIONIZE    ;D2 IS THE DIGIT COUNT FOR THE FRACTIONAL PART
  191. JUSTLEFT
  192.  EOR.L D5,D0            ;SET THE SIGN
  193.  CLR.L D1               ;NO ERROR
  194.  RTS
  195.  
  196.  DATA
  197.  
  198.  CNOP 0,4               ;ALIGN TO LONGWORD
  199.  
  200. DECBUF                  ;THIS IS TRICKY
  201.  DC.B 10,' '            ;START WITH LINEFEED AND SPACE
  202. DECBUF2
  203.  DC.B ' 0'              ;ROOM FOR NEG SIGN AND FIRST 0
  204. MATHNAME
  205.  DC.B 'mathffp.library' ;THIS AREA USED AS PART OF DECBUF, ALSO!!
  206.  DC.B 0,10,10,10        ;A FEW LINEFEEDS
  207.  EVEN
  208. DOSNAME
  209.  DC.B 'dos.library',0
  210.  EVEN
  211.  
  212.  END
  213.  
  214.